﻿// BufferHal.h : SSD仿真系统的缓冲区管理模块
// 负责缓冲区的分配、释放、数据读写及元信息管理
// 支持多种缓冲类型和扇区配置

#ifndef __BufferHal_h__
#define __BufferHal_h__

#include <map>
#include <boost/interprocess/sync/interprocess_mutex.hpp>

#include "BasicTypes.h"
#include "Buffer/Types.h"

/**
 * 默认扇区信息配置
 */
constexpr SectorInfo DefaultSectorInfo({9, false, 9});

/**
 * @class BufferHal
 * @brief SSD仿真系统的缓冲区管理模块，负责缓冲区的分配、释放、数据读写及元信息管理。
 */
class BufferHal
{
public:
    /**
     * @brief 构造函数，初始化缓冲区管理器
     */
    BufferHal();

    /**
     * @brief 初始化最大缓冲区大小（单位KB），预分配资源
     * @param maxBufferSizeInKB 最大缓冲区大小（KB）
     */
    void PreInit(const U32 &maxBufferSizeInKB);

    /**
     * @brief 设置隐式分配的扇区数量
     * @param sectorCount 隐式分配的扇区数
     */
    void SetImplicitAllocationSectorCount(const U32 &sectorCount);

    /**
     * @brief 分配缓冲区，指定类型和扇区数
     * @param type 缓冲区类型
     * @param sectorCount 扇区数
     * @param buffer 输出缓冲区结构体
     * @return 分配是否成功
     */
    bool AllocateBuffer(BufferType type, const U32 &sectorCount, Buffer &buffer);

    /**
     * @brief 分配缓冲区，使用隐式扇区数
     * @param type 缓冲区类型
     * @param buffer 输出缓冲区结构体
     * @return 分配是否成功
     */
    bool AllocateBuffer(BufferType type, Buffer &buffer);

    /**
     * @brief 释放缓冲区
     * @param buffer 要释放的缓冲区结构体
     */
    void DeallocateBuffer(const Buffer &buffer);

    /**
     * @brief 获取缓冲区的指针
     * @param buffer 缓冲区结构体
     * @return 缓冲区数据指针
     */
    U8 *ToPointer(const Buffer &buffer);

    /**
     * @brief 从缓冲区拷贝数据到目标地址
     * @param dest 目标地址
     * @param buffer 源缓冲区
     * @param bufferOffset 缓冲区起始扇区
     * @param sectorCount 拷贝扇区数
     */
    void CopyFromBuffer(U8 *const dest, const Buffer &buffer, const tSectorOffset &bufferOffset, const tSectorCount &sectorCount);

    /**
     * @brief 拷贝数据到缓冲区
     * @param src 源数据地址
     * @param buffer 目标缓冲区
     * @param bufferOffset 缓冲区起始扇区
     * @param sectorCount 拷贝扇区数
     */
    void CopyToBuffer(const U8 *const src, const Buffer &buffer, const tSectorOffset &bufferOffset, const tSectorCount &sectorCount);

    /**
     * @brief 设置扇区信息（如扇区大小、压缩模式等）
     * @param sectorInfo 扇区信息结构体
     * @return 设置是否成功
     */
    bool SetSectorInfo(const SectorInfo &sectorInfo);

    /**
     * @brief 获取当前扇区信息
     * @return 当前扇区信息结构体
     */
    SectorInfo GetSectorInfo() const;

    /**
     * @brief 计算缓冲区传输时的字节索引
     * @param type 缓冲区类型
     * @param offset 偏移量
     * @return 字节索引
     */
    U32 ToByteIndexInTransfer(BufferType type, U32 offset);

    /**
     * @brief 获取缓冲区最大字节数
     * @return 最大字节数
     */
    U32 GetBufferMaxSizeInBytes() const;

private:
    U32 _MaxBufferSizeInSector;                                              ///< 最大缓冲区扇区数
    U32 _CurrentFreeSizeInSector;                                            ///< 当前剩余可用扇区数
    tBufferHandle _CurrentBufferHandle;                                      ///< 当前缓冲区句柄（自增分配）
    std::unique_ptr<std::map<U32, std::unique_ptr<U8[]>>> _AllocatedBuffers; ///< 已分配缓冲区映射表（句柄->内存）
    SectorInfo _SectorInfo;                                                  ///< 当前扇区信息
    U32 _ImplicitAllocationSectorCount;                                      ///< 隐式分配的扇区数
    boost::interprocess::interprocess_mutex _Mutex;                          ///< 进程间互斥锁，保证多线程安全
};

#endif